#define __STDC_CONSTANT_MACROS
extern "C" {
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
}
#include <iostream>
#include <string>
using std::cout;
using std::endl;
using std::string;

string url = "rtmp://192.168.5.222:1935/hlsram/live0";

int main() { 
    cout << av_version_info() << endl;
    
    AVFormatContext * pFormatCtx = nullptr; 
    AVDictionary * avdic = nullptr;

    pFormatCtx = avformat_alloc_context();
    if(!pFormatCtx){
        cout << "failed to allocate format context" << endl;
        return -1;
    }
    //设置字典参数
    av_dict_set(&avdic,"rtmp_transport","udp",0);
    av_dict_set(&avdic,"max_delay","100",0);
    
    //1.初始化网络
    avformat_network_init(); //初始化网络
    //2.打开流
    if(avformat_open_input(&pFormatCtx,url.data(),nullptr,&avdic)!=0){
        cout << "could not open rtsm stream"<<endl;
        av_dict_free(&avdic);
        return -1;
    }
    cout << "open url success!" << endl;
    //3.找到流的信息
    if(avformat_find_stream_info(pFormatCtx,nullptr) < 0){
        cout << "could not find stream information" << endl;
        avformat_close_input(&pFormatCtx);
        return -1;
    }
    //打印媒体文件中流的信息
    av_dump_format(pFormatCtx,-1,url.data(),0);

    //4.找到最佳的流
    int videoStreamIdx = av_find_best_stream(pFormatCtx,AVMEDIA_TYPE_VIDEO,-1,-1,nullptr,0);
    if(videoStreamIdx < 0){
        cout << "could not find video stream" << endl;
        avformat_close_input(&pFormatCtx);
        return -1;
    }
    cout << "video stream index:" << videoStreamIdx;

    //5.读取数据包
    AVPacket * packet = av_packet_alloc();
    while(true){
        int ret = av_read_frame(pFormatCtx,packet);
        if(ret < 0){
                cout << "error reading frame:" << endl;
                break;
        }
        AVStream * stream = pFormatCtx->streams[packet->stream_index];

        if(packet->stream_index == videoStreamIdx){
            //将数据包发给客户端
            cout << "get a video packet,send to client!" << endl;
            //为了放防止一直打印，此处只运行一轮就停止
            break;
        }
        av_packet_unref(packet); //重置packet的状态
    }
    return 0;
}
